from django.db import models
from django.contrib.auth.models import User
from django.contrib import admin
from django.utils.safestring import mark_safe
from pypsqueak.group.models import Group

from django.conf import settings
from PIL import Image, ImageOps

class AbstractProfile(models.Model):
	""" Extended properties """
	def get_avatar_path( instance, filename ):
		return  'avatar_uploads/profile_%s/%s' % ( instance.pk, filename )
	avatar = models.ImageField( upload_to=get_avatar_path )
	foreground_font_color = models.CharField(
			max_length=200, default="rgb(3,3,3)" )
	foreground_canvas_color = models.CharField(
			max_length=200, default="rgb(251,252,229)" )
	background_font_color = models.CharField(
			max_length=200, default="rgb(0,0,0)" )
	background_canvas_color = models.CharField(
			max_length=200, default="rgb(5,91,37)" )

	# Ensure largest to smallest.
	avatar_sizes = [100,50,20]

	def save(self, force_insert=False,force_update=False):
		""" Automatically resize avator image for thumbnails """
		result = super(AbstractProfile, self).save(force_insert,force_update)

		if self.avatar:
			(path, sep, ext) = self.avatar.path.rpartition('.')
			img = Image.open('%s.%s' % (path, ext))
			(w,h) = img.size

			for size in self.avatar_sizes:

				thumb = img.copy()
				thumb.thumbnail( ((h/size)*w,size), Image.ANTIALIAS )
				thumb.convert('RGB')
				thumb.save('%s.%s.%s' % (path, size, ext))


	def link(self):
		""" Return a nicely formatted user-box """
		return mark_safe(
					u'''<a href="%(url)s"><img src="%(img)s">%(name)s</a>''' %
						{'url':self.get_absolute_url(),
						'img':self.get_avatar_url(20),
						'name':self.__unicode__()})


	def get_css_url(self):
		raise 'This should be defined in a subclass'

	class Meta:
		abstract = True

class GroupProfile(AbstractProfile):
	""" Extended properties for a group """

	group = models.ForeignKey(Group, unique=True)

	def __unicode__(self):
		return self.group.title

	def get_absolute_url(self):
		return '%s' % ( self.group.get_absolute_url() )
	def get_update_url(self):
		return '%s' % ( self.group.get_update_url() )

	def get_css_url(self):
		return '/GroupProfile.%s.css' % self.pk

	def get_avatar_url(self, height=50):
		if not self.avatar:
			return '/files/images/default_group.%s.jpg' % height
		else:
			(url,sep,ext) = self.avatar.url.rpartition('.')
			return '%s.%s.%s' % (url,height,ext)


	def permission(self, user, permission):
		""" Defer permissions to owning group model """
		return self.group.permission(user, permission)


	class Admin:
		pass



class UserProfile(AbstractProfile):
	""" Extended properties for a user """

	about = models.TextField()
	user = models.ForeignKey(User, unique=True)
	def get_avatar_path( instance, filename ):
		return  'avatar_uploads/%s/%s' % ( instance.user.username, filename )


	def __unicode__(self):
		name = self.user.get_full_name()
		if len(name)>0:
			return name
		else:
			return self.user.username


	def get_absolute_url(self):
		return '/%s/profile/' % ( self.user.username )
	def get_update_url(self):
		return '/%s/profile/update/' % ( self.user.username )

	def get_css_url(self):
		return '/UserProfile.%s.css' % self.pk

	def get_avatar_url(self,height=50):
		if not self.avatar:
			return '/files/images/default_user.%s.jpg' % height
		else:
			(url,sep,ext) = self.avatar.url.rpartition('.')
			return '%s.%s.%s' % (url,height,ext)


	def permission(self, user, permission):
		""" Defer permissions to owning user model """
		return self.user.permission(user, permission)


	class Admin:
		pass


## Update User object through MonkeyPatching.

def monkeypatch_method(cls):
	"""
	Add ability to add a decorator to a class for adding additional functionality
	See http://mail.python.org/pipermail/python-dev/2008-January/076194.html
	"""
	def decorator(func):
		setattr(cls, func.__name__,func)
		return func
	return decorator

@monkeypatch_method(User)
def get_profile(self):
	"""	Make User's get_profile function create new profile if None. """

	profiles = UserProfile.objects.filter( user__pk = self.pk )
	if len(profiles) == 0:
		p = UserProfile(user=self)
		p.save()
	else:
		p = profiles[0]

	return p

@monkeypatch_method(Group)
def get_profile(self):
	"""	Make Group's get_profile function create new profile if None. """

	profiles = GroupProfile.objects.filter( group__pk = self.pk )
	if len(profiles) == 0:
		p = GroupProfile(group=self)
		p.save()
	else:
		p = profiles[0]

	return p


@monkeypatch_method(User)
def get_absolute_url(self):
	""" Returns correct url for a user. """

	return '/%s/' % self.username


@monkeypatch_method(User)
def permission(self, user, permission):
	""" Determine if the user has permission to edit this user """
	if permission=='update':
		return (user.pk == self.pk)
	elif permission=='delete':
		return False
	elif permission=='select':
		return True
	else:
		raise Exception, 'Invalid permission'


@monkeypatch_method(User)
def get_full_name(self):
	""" Update to return username if no last/first names are set """
	name = '%s %s' % (self.first_name, self.last_name)

	if len(name) == 1:
		return self.username
	else:
		return (name)


@monkeypatch_method(User)
def get_short_name(self):
	""" Update to return username if no first name is set """
	if len(self.first_name) < 1:
		return self.username
	else:
		return self.first_name